from kivy.logger import Logger
from nmj.core.main import NMJUpdater
from nmj.sqlite.tables import Show, Video
from nmjeditor.data_access.command_runner import Message, CommandRunner
import ConfigParser
import os

CONFFILE=os.path.join(os.environ["HOME"], ".nmjeditor", "nmjeditor.conf")

def public(functor):
	functor.public = True
	return functor

class ControllerProxy(object):
	def __init__(self, queue):
		self.queue = queue

	def send_message(self, method, *args, **kwargs):
		self.queue.put(Message(method, *args, **kwargs))

	def __getattr__(self, name):
		if not getattr(getattr(Controller, name), "public", False):
			raise AttributeError("%s is not a public method")
		def wrapper(*args, **kwargs):
			return self.send_message(name, *args, **kwargs)
		return wrapper

class Controller(CommandRunner):
	def __init__(self, command_queue, drawer, **kwargs):
		CommandRunner.__init__(self, command_queue)
		if not os.path.isfile(CONFFILE):
			os.makedirs(os.path.dirname(CONFFILE))
			kwargs.get("file_factory", file)(CONFFILE, "w+").close()
		self._config = kwargs.get("config_factory", ConfigParser.ConfigParser)()
		self._config.read(CONFFILE)
		self.nmj_factory = kwargs.get("nmj_factory", NMJUpdater)
		self.message_factory = kwargs.get("message_factory", Message)
		self.drawer = drawer

	def notify(self, message):
		super(Controller, self).notify(message)
		self.drawer.ask_update()

	def thread_started(self):
		self._nmj = self.nmj_factory()
		self.load_libraries()

	def load_libraries(self):
		try:
			lib_list = self._config.get("media", "libraries")
			for rootdir in eval(lib_list):
				self._nmj.add_library(rootdir)
		except ConfigParser.NoSectionError:
			Logger.exception("I think, you should declare '[media]' section in your %s config file", CONFFILE)
		except ConfigParser.NoOptionError:
			Logger.exception("I think, you should declare 'libraries' key in your %s config file", CONFFILE)
		except AssertionError:
			raise
		except:
			Logger.exception("""Your %s config file seems to be badly formatted, it should be like:
[media]
libraries="/path/to/the/first/library", "/path/to/the/second/library", ...
""", CONFFILE)

	@public
	def update(instance):
		class ProgressBarUpdater(object):
			def __init__(self, max_value):
				self.max = max_value
				instance.notify(Message("on_show_max", max_value))
				Logger.info("ProgressBarUpdater(%d)", self.max)

			def start(self):
				instance.notify(Message("on_scan_progress", 0))
				Logger.info("ProgressBarUpdater.start()")

			def finish(self):
				instance.notify(Message("on_scan_progress", self.max))
				Logger.info("ProgressBarUpdater.finish()")

			def update(self, rank):
				instance.notify(Message("on_scan_progress", rank))
				Logger.info("ProgressBarUpdater.update(%d)", rank)


		instance._nmj.update(ProgressBarUpdater)

	def get_libraries(self):
		return self._nmj.libraries

	@public
	def get_posters(self, show):
		posters = show.library.get_posters(show=show)
		for poster in posters:
			self.notify(self.message_factory("on_poster", poster))

	@public
	def get_wallpapers(self, show):
		wallpapers = show.library.get_wallpapers(show=show)
		for wallpaper in wallpapers:
			self.notify(self.message_factory("on_wallpaper", wallpaper))

	@public
	def update_poster(self, show, poster):
		poster_path = show.library.update_poster(show, poster)
		self.notify(Message("on_poster_updated", poster_path))

	@public
	def update_wallpaper(self, show, wallpaper):
		wallpaper_path = show.library.update_wallpaper(show, wallpaper)
		self.notify(Message("on_wallpaper_updated", wallpaper_path))

	@public
	def update_show(self, show, movie_info):
		show = show.library.update_show(show, movie_info)
		self.notify(Message("on_show_updated", show))

	@public
	def get_shows(self):
		shows = []
		for lib in self._nmj.libraries:
			s = self._nmj.get_all(Show)
			for show in s:
				show.library = lib
			shows.extend(s)
		self.notify(self.message_factory("on_show_max", len(shows)))
		shows.sort()
		for show in shows:
			video = show.library.get_all(Video, show_id=show.show_id)[0]
			show.path = video.path
			if show.detail_poster:
				show.detail_poster = os.path.join(lib.base_directory, show.detail_poster)
			if show.wallpaper:
				show.wallpaper = os.path.join(lib.base_directory, show.wallpaper)
			self.notify(self.message_factory("on_show", show))

	@public
	def research(self, show):
		videos = show.library.get_all(Video, show_id=show.show_id)
		Logger.info("videos = %s", videos)
		Logger.info("videos[0] = %s", videos[0])
		movies = show.library.search(os.path.splitext(os.path.basename(videos[0].path))[0])
		for movie in movies:
			movie.path = os.path.join(show.library.base_directory, videos[0].path)
			self.notify(self.message_factory("on_search_movie_result", movie))

	@public
	def get_synopsis(self, show=None, title=None):
		self.notify(
			self.message_factory(
				"on_synopsis",
				self._nmj.get_synopsis(show=show, title=title)
			)
		)



